package com.shadowtorcher.dragonstreasure.controller;

import com.shadowtorcher.dragonstreasure.config.Config;
import com.shadowtorcher.dragonstreasure.filelogic.StaticFileLogic;
import com.shadowtorcher.dragonstreasure.url.DownloadURL;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

@RestController
public class DownloadController {
    @RequestMapping(value = "/download/{uuid}/{username}/{time}/{check_code}/{file_name}", method = RequestMethod.GET)
    public void doDownload(HttpServletRequest request, HttpServletResponse response, @PathVariable String uuid, @PathVariable String username, @PathVariable String time, @PathVariable String check_code, @PathVariable String file_name) {
        DownloadURL downloadURL = new DownloadURL();
        downloadURL.setUUID(uuid);
        downloadURL.setUsername(username);
        downloadURL.setTime(time);
        downloadURL.setCheckCode(check_code);
        downloadURL.setFileName(file_name);
        System.out.println("[INFO]down file" + downloadURL.getUUID());
        try {
            // 检查请求
            if (!StaticFileLogic.checkFileURL(downloadURL)) {
                response.setStatus(403);
                return;
            }

            // 打开文件
            File file = new File(Config.PATH + "/" + downloadURL.getUUID() + ".data");
            if (!file.exists()) {
                response.setStatus(404);
                return;
            }
            response.addHeader("Content-Length", String.valueOf(file.length()));
            // 断点续传
            if (request.getHeader("Range") != null) {
                String[] ranges = request.getHeader("Range").split("=")[1].split(",");// bytes=500-600
                StringBuilder contentRange = new StringBuilder("bytes ");
                for (String range : ranges) {
                    String[] r = range.split("-");
                    long start = 0;
                    long end = Long.MAX_VALUE;
                    switch (r.length) {
                        case 0:
                            throw new IOException("Illegal migration");
                        case 2:
                            end = Long.parseLong(r[1]);
                        case 1:
                            start = Long.parseLong(r[0]);
                    }
                    contentRange.append(start).append("-").append(end);
                    writeToString(file, start, end, response.getOutputStream());
                }
                response.addHeader("content-range", contentRange.toString() + "/" + file.length());
            } else {
                writeToString(file, 0, file.length(), response.getOutputStream());
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.setStatus(403);
        }
    }

    private void writeToString(File file, long start, long end, OutputStream outputStream) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(file);
        long skip = fileInputStream.skip(start);
        if (skip != start) {
            throw new EOFException();
        }
        byte[] buffer = new byte[4096];
        int length;
        while ((length = fileInputStream.read(buffer)) != -1 && start <= end) {
            outputStream.write(buffer, 0, length);
            start += length;
        }
        fileInputStream.close();
    }
}
